package com.cssy.yd.logic.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.byd.acegiext.domain.User;
import com.cssy.yd.logic.dao.LogicSoDAO;
import com.cssy.yd.logic.dao.LogicSoItemDAO;
import com.cssy.yd.logic.dao.LogicSoWareDAO;
import com.cssy.yd.logic.dao.LogicSoWareItemBatchDAO;
import com.cssy.yd.logic.dao.LogicSoWareItemDAO;
import com.cssy.yd.logic.dao.LogicSoWareItemFreezedealbatchDAO;
import com.cssy.yd.logic.dao.LogicSoWarefreezeDAO;
import com.cssy.yd.logic.dao.LogicSoWarefreezeItemDAO;
import com.cssy.yd.logic.dao.LogicSoWarefreezedealDAO;
import com.cssy.yd.logic.dao.LogicSoWarefreezedealItemBatchDAO;
import com.cssy.yd.logic.dao.LogicSoWarefreezedealItemDAO;
import com.cssy.yd.logic.entity.LogicPoReturnItemBatchDO;
import com.cssy.yd.logic.entity.LogicSoDO;
import com.cssy.yd.logic.entity.LogicSoItemDO;
import com.cssy.yd.logic.entity.LogicSoWareDO;
import com.cssy.yd.logic.entity.LogicSoWareItemBatchDO;
import com.cssy.yd.logic.entity.LogicSoWareItemDO;
import com.cssy.yd.logic.entity.LogicSoWareItemFreezedealbatchDO;
import com.cssy.yd.logic.entity.LogicSoWarefreezeDO;
import com.cssy.yd.logic.entity.LogicSoWarefreezeItemDO;
import com.cssy.yd.logic.entity.LogicSoWarefreezedealDO;
import com.cssy.yd.logic.entity.LogicSoWarefreezedealItemBatchDO;
import com.cssy.yd.logic.entity.LogicSoWarefreezedealItemDO;
import com.cssy.yd.logic.entity.LogicWhAffDO;
import com.cssy.yd.logic.service.ILogicSoWareService;
import com.cssy.yd.logic.service.ILogicWhAffStockService;
import com.cssy.yd.logic.util.logic.LogicSoBeanUtil;
import com.plat.exception.SyBaseException;
import com.plat.helper.SearchCondition;
import com.plat.helper.SearchConditions;
import com.plat.helper.SearchResult;
import com.plat.util.DateUtils;
import com.plat.util.GlobalResLoader;
import com.plat.util.IDCodeTypeUtil;
import com.plat.util.SessionUtil;
import com.yuendong.sy.po.code.SyCode;
import com.yuendong.sy.service.code.SyCodeType;
import com.yuendong.sy.service.code.impl.SyCodeService;

@Service("logicSoWareService")
public class LogicSoWareServiceImpl implements ILogicSoWareService {

	private static final Logger logger = Logger.getLogger(LogicSoWareServiceImpl.class);

	@Resource(name = "logicSoWareDAO")
	private LogicSoWareDAO logicSoWareDAO;

	@Resource(name = "logicSoWareItemDAO")
	private LogicSoWareItemDAO logicSoWareItemDAO;
	
	@Resource(name = "logicSoDAO")
	private LogicSoDAO logicSoDAO;
	
	@Resource(name = "logicSoItemDAO")
	private LogicSoItemDAO logicSoItemDAO;

	@Resource(name = "logicSoWarefreezedealDAO")
	private LogicSoWarefreezedealDAO logicSoWarefreezedealDAO;
	@Resource(name = "logicSoWarefreezedealItemDAO")
	private LogicSoWarefreezedealItemDAO logicSoWarefreezedealItemDAO;
	
	@Resource(name = "logicSoWarefreezeDAO")
	private LogicSoWarefreezeDAO logicSoWarefreezeDAO;
	@Resource(name = "logicSoWarefreezeItemDAO")
	private LogicSoWarefreezeItemDAO logicSoWarefreezeItemDAO;
	
	@Resource(name = "logicWhAffStockService")
	private ILogicWhAffStockService logicWhAffStockService;

	@Resource(name="logicSoWareItemBatchDAO")
	private LogicSoWareItemBatchDAO logicSoWareItemBatchDAO;
//	@Resource(name = "logicFreightageDAO")
//	LogicFreightageDAO logicFreightageDAO;

//	@Resource(name = "logicPoWareDAO")
//	private LogicPoWareDAO logicPoWareDAO;

//	@Resource(name = "logicPoWareItemDAO")
//	private LogicPoWareItemDAO logicPoWareItemDAO;

	@Resource(name = "syCodeService")
	private SyCodeService syCodeService;

	@Resource(name="logicSoWarefreezedealItemBatchDAO")
	private LogicSoWarefreezedealItemBatchDAO logicSoWarefreezedealItemBatchDAO;
	
	@Resource(name="logicSoWareItemFreezedealbatchDAO")
	private LogicSoWareItemFreezedealbatchDAO logicSoWareItemFreezedealbatchDAO;
	
	@Override
	public SearchResult findListByExample(SearchConditions scs)throws SyBaseException {
		SearchResult rs = new SearchResult(scs);
		rs.setResults(logicSoWareDAO.find(scs));
		rs.setRecordCount(logicSoWareDAO.count(scs));
		return rs;
	}

	@Override
	public Integer delete(String id, User user) throws SyBaseException {
		return logicSoWareDAO.deleteLogicSoWareDOByPrimaryKey(id);
	}

	@Override
	public Integer update(LogicSoWareDO t, User user) throws SyBaseException {
		t.setDuuser(user.getName());
		t.setDutime(new Date());
		return logicSoWareDAO.updateLogicSoWareDO(t);
	}

	@Override
	public LogicSoWareDO save(LogicSoWareDO t, User user)
			throws SyBaseException {
		t.setDcruser(user.getName());
		t.setDctime(new Date());
		logicSoWareDAO.insertLogicSoWareDO(t);
		return null;
	}

	@Override
	public LogicSoWareDO findListById(String id) throws SyBaseException {
		return logicSoWareDAO.findLogicSoWareDOByPrimaryKey(id);
	}

	@Override
	public void soWareSave(HttpServletRequest request, LogicSoWareDO curAP)
			throws SyBaseException {
		try {
			String itemdata = request.getParameter("itemdata");
			List<LogicSoWareItemDO> swItemList = JSONArray.parseArray(itemdata,LogicSoWareItemDO.class);
			
			String itemdata2 = request.getParameter("itemdata2");
			List<LogicSoWareItemDO> swItemList2 = JSONArray.parseArray(itemdata2,LogicSoWareItemDO.class);
			
			/*
			 * 获取操作 0为保存(草稿状态) 
			 * 1为提交(待审核状态) 
			 * 2为二级结案(提交二级结案) 
			 * 3为二级驳回到草稿
			 */
			String paramflag = request.getParameter("paramflag");
			int iToFlag = -1;
			iToFlag = Integer.parseInt(paramflag);
			curAP.setBillstatus(Integer.parseInt(paramflag));

//			boolean bt = true;

			User user = SessionUtil.getUser(request);
			Date curDate = new Date();

			if (StringUtils.isBlank(curAP.getId())) {
				/* 新增 设置状态billstatus= 0 */
				
				//---start 判断单据是否存在未完成处理的记录
				if(StringUtils.isBlank(curAP.getSoNo())){
					throw new SyBaseException("销售订单编号参数为空");
				}
				SearchConditions scs = new SearchConditions();
				scs.addCondition("so_no", curAP.getSoNo(), SearchCondition.OP_EQUAL);
				scs.addCondition("billstatus", "2", SearchCondition.OP_NOTEQUAL);
				Integer count = logicSoWareDAO.count(scs);
				if(null != count && count > 0){
					throw new SyBaseException(curAP.getSoNo()+"销售订单存在未处理的销售出库单");
				}
				//---end 判断单据是否存在未完成处理的记录
				
				
				String id = IDCodeTypeUtil.getId();
				curAP.setId(id);
				curAP.setNo(syCodeService.getCode("XS","XS",SyCode.DATE_YYMM,5));

				curAP.setDcruser(user.getName());
				curAP.setDctime(curDate);

				curAP.setPaymentstatus(0);// 支付状态-未收款

				curAP.setLister(user.getName());
				curAP.setListerName(user.getRealName());

				// 日期转换处理
				String deliveryDate = request.getParameter("deliveryDate");
				if (StringUtils.isNotBlank(deliveryDate)) {
					curAP.setDeliveryDate(DateUtils.stringToDate(deliveryDate));
				}
				
				curAP.setWareStatus(0);//出库标记-未出库

				logicSoWareDAO.insertLogicSoWareDO(curAP);

				curAP.setId(id);// 添加上，否则插入之后ID为0
				saveOrUpdateItems(swItemList,swItemList2, curAP);
				// for(int i=0;i<axxlist.size();i++){
				// axxlist.get(i).setSowareId(id);
				// axxlist.get(i).setId(IDCodeTypeUtil.getId());
				// logicSoWareItemDAO.insertLogicSoWareItemDO(axxlist.get(i));
				// }

			} else if (iToFlag >= 0 && iToFlag <= 3) {
				// 修改

				LogicSoWareDO bean = logicSoWareDAO.findLogicSoWareDOByPrimaryKey(curAP.getId());
				if (null == bean.getVersion()
						|| !bean.getVersion().equals(curAP.getVersion())) {
					throw new SyBaseException("版本号异常，请刷新后重新编辑");
				}
				bean.setBillstatus(iToFlag);

				int result = 0;
				if (1 == iToFlag) {// 提交二级审核
					curAP.setBillstatus(bean.getBillstatus());

					curAP.setDctime(bean.getDctime());
					curAP.setDcruser(bean.getDcruser());

					curAP.setLister(user.getName());
					curAP.setListerName(user.getRealName());
					curAP.setDutime(curDate);
					curAP.setDuuser(user.getName());

					// 日期转换处理
					String deliveryDate = request.getParameter("deliveryDate");
					if (StringUtils.isNotBlank(deliveryDate)) {
						curAP.setDeliveryDate(DateUtils.stringToDate(deliveryDate));
					}

					// 持久化
					result = logicSoWareDAO.updateLogicSoWareDO(curAP);
					if (result == 1) {
						saveOrUpdateItems(swItemList,swItemList2, curAP);
					}
				} else if (2 == iToFlag) {// 二级审核完结-出库处理

					/* 处理库存 */
					
					/*
					 * 出库处理：结合订单item、当前出库单item，冻结处理单item，item相应仓库仓位库存数量
					 * hf：仓库出库的条件：物料编码/ID，批次，仓库编码，等级（冻结的无论等级）。销售出库数量只增不减。
					 * @author huang.xuming[2013-08-08]
					 * 
					 * 出库单对应的销售订单是否可出库
					 * boolean 订单完全出库标记=true;
					 * 
					 * 冻结库存itemList = 根据订单编号+当前仓库+当前物料编号，查询是否有冻结库存
					 * 冻结库存itemMap--key(物料编号+批次号)，重复时累加
					 * 
					 * 
					 * 
					 * for(出库单相应的订单item){//根据订单编号或者ID
					 * 		当前订单当前item;
					 * 
					 * 		for(当前出库单item){
					 * 			if(当前订单当前item.物料编号 == 当前出库单当前item.物料编号){
					 * 				当前订单当前item.新已出库数量= 旧已出库数量+当前出库单当前item.出库数量；
					 * 				
					 * 				if(新已出库数量 <= 当前订单当前item.订单数量 ){
					 * 					
					 * 					在可用库存中的出库数量 = 当前出库单当前item.出库数量；
					 *  				//冻结库存优先出库，再从可用库存出库 --无仓位，有批次
					 * 					if(冻结库存itemMap存在相应冻结库存，并且大于0){
					 * 						冻结库存中出库数量=(出库数量>冻结数量)?冻结数量:出库数量;
					 * 						在可用库存中的出库数量 -=  冻结库存中出库数量;
					 * 						
					 * 						订单当前item.冻结数量 -= 冻结库存中出库数量;
					 * 						
					 * 						冻结仓库出库处理
					 *  				}
					 * 					
					 * 					if(在可用库存中的出库数量 > 0){
					 * 						//根据仓库编码+物料编号+批次+等级，查询可用库存数量
					 * 						if(可用库存数量>=在可用库存中的出库数量){
					 * 							可用仓库出库处理
					 * 						}
					 * 						
					 * 					}else if(在可用库存中的出库数量 == 0){
					 * 						//全部出库都从冻结库存中出
					 * 					}
					 * 				}else{
					 * 					错误！
					 * 				}
					 * 				break;
					 * 			}
					 * 		}
					 * 
					 * 		if((当前订单item.订单数量-当前订单item.已出库数量) > 0){
					 * 			订单完全出库标记=false;
					 * 		}
					 * }
					 * 
					 * 订单的出库标记设置--部分出库or完全出库
					 * 
					 * 冻结库存itemMap持久化
					 * 当前订单状态+订单item持久化
					 * 当前出库单状态、出库单item持久化
					 * 
					 */
					
					
					if(null == swItemList && null == swItemList2){
						throw new SyBaseException(curAP.getSoNo()+"编号出库单，前台传入的销售出库单产品列表(swItemList和swItemList2)json转换后为空对象");
					}
					
					//获取相应销售订单信息
					LogicSoDO logicSoDO = findLogicSoDOByNo(curAP.getSoNo());
					if(null == logicSoDO){
						throw new SyBaseException(curAP.getSoNo()+"编号的销售订单不存在");
					}
						
					// 检查销售订单是否可出库
					if(2 == logicSoDO.getWareStatus()){
						throw new SyBaseException(curAP.getNo()+"编号出库单相应的销售单已全部出库");
					}
					if(4!=logicSoDO.getBillstatus() && 5!=logicSoDO.getBillstatus()){
						throw new SyBaseException(curAP.getNo()+"编号出库单相应的销售单的未完结");
					}
						
					//出库单对应的销售订单items
					List<LogicSoItemDO> soItems = logicSoItemDAO.findItemListBysoId(logicSoDO.getId());
					if(null == soItems){
						throw new SyBaseException(logicSoDO.getId()+"编号的销售订单产品列表不存在");
					}
					
					
//					//出库单相应的冻结产品items
//					//20130910 修改
////					List<LogicSoWarefreezedealItemDO> swfdItems = findSoWarefreezedealItemsBySoNo(curAP.getSoNo());
//					Map<String, List<LogicSoWarefreezedealItemDO>>  swfdItemMap = new HashMap<String, List<LogicSoWarefreezedealItemDO>>();
//					List<LogicSoWarefreezedealItemDO> swfdItems = new ArrayList<LogicSoWarefreezedealItemDO>();
//					SearchConditions scs = new SearchConditions();
//					scs.addCondition("so_no", curAP.getSoNo(), SearchCondition.OP_EQUAL);
//					scs.addCondition("billstatus", "2", SearchCondition.OP_EQUAL);//完结的冻结处理单据
//					List<LogicSoWarefreezedealDO> ls = logicSoWarefreezedealDAO.find(scs);
//					if(null != ls && ls.size() > 0){
//						for(LogicSoWarefreezedealDO logicSoWarefreezedealDO :ls){
//							swfdItems = logicSoWarefreezedealItemDAO.findItemListByswfdId(logicSoWarefreezedealDO.getId());
//							
//							groupSoWarefreezedealItemsMap(swfdItemMap,logicSoWarefreezedealDO,swfdItems);
//						}
//			        }
					
					//普通出库
					if(null != swItemList){
						
						
						for(LogicSoWareItemDO curSwItem: swItemList){
							//出库单当前产品实发基本单位数量 -- 当前需要出库数量
							Double curCkBQty  = curSwItem.getProdBSfquantity();
							Double curCkQty  = curSwItem.getProdSfquantity();
							if(curCkBQty <=0 ){
								throw new SyBaseException(curAP.getNo()+"销售出库单，"+curSwItem.getProdNo()+"产品的出库数量需大于0");
							}
							for(LogicSoItemDO curSoItem : soItems){
								if(LogicSoBeanUtil.getInstance().isSameMaterial(curSoItem, curSwItem)){
									
									if(curCkBQty > LogicSoBeanUtil.getInstance().calcSoItemCanFreezeBQty(curSoItem)){
										throw new SyBaseException(curAP.getSoNo()+"编号销售订单，前台传入的实发数量超过订单剩余可出库数量。可出库基本数量为："+LogicSoBeanUtil.getInstance().calcSoItemCanFreezeBQty(curSoItem));
									}
									
									
									
									/* 仓库的可用库存中出库 */
										
									//查询物料在指定仓库中的总数量
									double tmpTotal = logicWhAffStockService.getSumQuantityByWhInfoAndMaInfoAndStatus(curSwItem.getProdNo(), curAP.getWhcode(), curSwItem.getStatus());
									if(curCkBQty >= tmpTotal){
										//TODO 生成生产建议单
										logger.debug("生成生产建议单");
											
									}
										
									curSwItem.setProdPrice(curSoItem.getProdPrice());
									ptckWhAff(curAP, curSwItem, curCkQty, curCkBQty, SessionUtil.getUser(request));

									
									//销售订单当前产品已出库数量-新
									Double newCkQty = curSoItem.getCkQuantity()+curCkQty;
									Double newCkBQty= curSoItem.getCkBQuantity()+curCkBQty;
									
									// 当前出库单item设置，以备持久化
//									curSwItem.setCkQuantity(newCkQty);
//									curSwItem.setCkBQuantity(newCkBQty);
//									curSwItem.setFrozenQuantity(frozenQuantity);
//									curSwItem.setFrozenBQuantity(frozenBQuantity);
//									logicSoWareItemDAO.updateLogicSoWareItemDO(curSwItem);
									
									// 当前订单item持久化
									LogicSoItemDO soItemToDb = new LogicSoItemDO();
									soItemToDb.setId(curSoItem.getId());
									soItemToDb.setCkQuantity(newCkQty);
									soItemToDb.setCkBQuantity(newCkBQty);
									
									logicSoItemDAO.updateLogicSoItemDO(soItemToDb);
									
									// 当前订单item设置，以备后面循环的持久化
									curSoItem.setCkQuantity(soItemToDb.getCkQuantity());
									curSoItem.setCkBQuantity(soItemToDb.getCkBQuantity());
								}
							}
						}
					}

					//=============================================
					/*冻结出库*/
					
					//缓存，以便计算冻结标记-key 冻结申请单编码
					Map<String ,LogicSoWarefreezeDO> soWarefreezeMap = new HashMap<String, LogicSoWarefreezeDO>();
					Map<String ,List<LogicSoWarefreezeItemDO>> soWarefreezeItemMap = new HashMap<String, List<LogicSoWarefreezeItemDO>>();
					//缓存，以便计算冻结标记-key 冻结处理单编码
					Map<String ,LogicSoWarefreezedealDO> soWarefreezedealMap = new HashMap<String, LogicSoWarefreezedealDO>();
					Map<String ,List<LogicSoWarefreezedealItemDO>> soWarefreezedealItemMap = new HashMap<String, List<LogicSoWarefreezedealItemDO>>();
					
					
					
					/*冻结出库*/
					if(null != swItemList2){
						
						for(LogicSoWareItemDO curSwItem2: swItemList2){
							//出库单当前产品实发基本单位数量 -- 当前需要出库数量
							Double curCkBQty  = curSwItem2.getProdBSfquantity();
							Double curCkQty  = curSwItem2.getProdSfquantity();
							
							if(curCkBQty <=0 ){
								throw new SyBaseException(curAP.getNo()+"销售出库单，"+curSwItem2.getProdNo()+"产品的冻结出库数量需大于0");
							}
							for(LogicSoItemDO curSoItem : soItems){
								if(LogicSoBeanUtil.getInstance().isSameMaterial(curSoItem, curSwItem2)){
									
									if(curCkBQty > curSoItem.getFrozenBQuantity()){
										throw new SyBaseException(curAP.getSoNo()+"编号销售订单，前台传入的"+curSoItem.getProdNo()+"产品实发数量超过订单剩余可出库数量。可出库基本数量为："+LogicSoBeanUtil.getInstance().calcSoItemCanFreezeBQty(curSoItem));
									}
									
									/* 冻结出库 */
									curSwItem2.setProdPrice(curSoItem.getProdPrice());
									djckWhAff(curAP, curSwItem2, curCkQty, curCkBQty, SessionUtil.getUser(request));
									
									// 当前出库单item设置，以备持久化
//									curSwItem2.setCkQuantity(newCkQty);
//									curSwItem2.setCkBQuantity(newCkBQty);
//									curSwItem2.setFrozenQuantity(curSwItem2.getFrozenQuantity()-curCkQty);
//									curSwItem2.setFrozenBQuantity(curSwItem2.getFrozenBQuantity()-curCkBQty);
//									logicSoWareItemDAO.updateLogicSoWareItemDO(curSwItem2);
									
									// 当前订单item持久化
									curSoItem.setCkQuantity(curSoItem.getCkQuantity()+curCkQty);
									curSoItem.setCkBQuantity(curSoItem.getCkBQuantity()+curCkBQty);
									curSoItem.setFrozenCkBQty(curSoItem.getFrozenCkBQty()+curCkBQty);
									curSoItem.setFrozenCkQty(curSoItem.getFrozenCkQty()+curCkQty);
									curSoItem.setFrozenQuantity(curSoItem.getFrozenQuantity()-curCkQty);
									curSoItem.setFrozenBQuantity(curSoItem.getFrozenBQuantity()-curCkBQty);
									
									logicSoItemDAO.updateLogicSoItemDO(curSoItem);
									
								}
							}
							
							/* 冻结处理单 */
							SearchConditions scs = new SearchConditions();
							scs.addCondition("no", curSwItem2.getSourceBillNo(), SearchCondition.OP_EQUAL);
							scs.addCondition("billstatus", "2", SearchCondition.OP_EQUAL);//完结的冻结处理单据
							scs.addCondition("unfrozen_status", "0,1", SearchCondition.OP_IN);//冻结状态的单据
							List<LogicSoWarefreezedealDO> loWarefreezedealDOList = logicSoWarefreezedealDAO.find(scs);
							if(null == loWarefreezedealDOList || 0==loWarefreezedealDOList.size()){
								throw new SyBaseException(curSwItem2.getSourceBillNo()+"冻结处理单不可冻结出库");
							}
							LogicSoWarefreezedealDO cwfd = loWarefreezedealDOList.get(0);
							List<LogicSoWarefreezedealItemDO> cwfdItems = logicSoWarefreezedealItemDAO.findItemListByswfdId(cwfd.getId());
							for (LogicSoWarefreezedealItemDO item : cwfdItems) {
								// 匹配的产品
								if(item.getId()!=null){
									List<LogicSoWarefreezedealItemBatchDO> list = logicSoWarefreezedealItemBatchDAO.findBywfdId(item.getId());
									if(curSwItem2.getItemBatch()!=null && !"".equals(curSwItem2.getItemBatch().trim())){
										List<LogicSoWareItemFreezedealbatchDO> batchDOs =JSONArray.parseArray(curSwItem2.getItemBatch(), LogicSoWareItemFreezedealbatchDO.class);
										for (LogicSoWarefreezedealItemBatchDO logicSoWarefreezedealItemBatchDO : list) {
											for (LogicSoWareItemFreezedealbatchDO lFreezedealbatchDO : batchDOs) {
												if(lFreezedealbatchDO.getProdBatch().equals(logicSoWarefreezedealItemBatchDO.getProdBatch()) && lFreezedealbatchDO.getProdNo().equals(logicSoWarefreezedealItemBatchDO.getProdNo()) && lFreezedealbatchDO.getMaterialsid().equals(logicSoWarefreezedealItemBatchDO.getMaterialsid())){
													logicSoWarefreezedealItemBatchDO.setCkBQuantity((logicSoWarefreezedealItemBatchDO.getCkBQuantity()==null?0.0:logicSoWarefreezedealItemBatchDO.getCkBQuantity())+lFreezedealbatchDO.getProdBSfquantity());
													logicSoWarefreezedealItemBatchDO.setCkQuantity((logicSoWarefreezedealItemBatchDO.getCkQuantity()==null?0.0:logicSoWarefreezedealItemBatchDO.getCkQuantity())+lFreezedealbatchDO.getProdSfquantity());
												}
											}
										logicSoWarefreezedealItemBatchDAO.updateLogicSoWarefreezedealItemBatchDO(logicSoWarefreezedealItemBatchDO);
										}
									item.setItemBatch(JSONArray.toJSONString(list));
									logicSoWarefreezedealItemDAO.updateLogicSoWarefreezedealItemDO(item);
									}
								}
								if (cwfd.getWhcode().equals(curAP.getWhcode())
										&& item.getProdNo().equals(curSwItem2.getProdNo())
										&& item.getProdBatch().equals(curSwItem2.getProdBatch())
										&& item.getStatus().equals(curSwItem2.getStatus())) {
									//足够的可冻结出库数量 
									if(curCkBQty > LogicSoBeanUtil.getInstance().calcFreezeDealItemCanUnfreezeBQty(item)){
										throw new SyBaseException(cwfd.getNo()+"冻结处理单据,"+item.getProdNo()+"产品编码,冻结数量不足出库");
									}
									
									item.setDjckBQuantity(item.getDjckBQuantity()+curCkBQty);
									item.setDjckQuantity(item.getDjckQuantity()+curCkQty);
									//持久化
									logicSoWarefreezedealItemDAO.updateLogicSoWarefreezedealItemDO(item);
									
								}
							}
							//缓存，以便计算冻结标记
							soWarefreezedealMap.put(cwfd.getNo(), cwfd);
							soWarefreezedealItemMap.put(cwfd.getNo(), cwfdItems);
									
							/* 冻结申请单 */
							SearchConditions scs2 = new SearchConditions();
							scs2.addCondition("no", cwfd.getSowarefreezeNo(), SearchCondition.OP_EQUAL);
							scs2.addCondition("billstatus", "2", SearchCondition.OP_EQUAL);//完结的冻结处理单据
							//原:scs.addCondition("frozen_status", "1,2", SearchCondition.OP_IN);//冻结状态的单据
							scs2.addCondition("frozen_status", "1,2", SearchCondition.OP_IN);//冻结状态的单据
							List<LogicSoWarefreezeDO> swfList = logicSoWarefreezeDAO.find(scs2);
							if(null == swfList || 0==swfList.size()){
								throw new SyBaseException(cwfd.getSowarefreezeNo()+"冻结申请单不可冻结出库");
							}
							LogicSoWarefreezeDO swfDo = swfList.get(0);
							List<LogicSoWarefreezeItemDO> cwfItems = logicSoWarefreezeItemDAO.findItemListBySoWareFreezeId(swfDo.getId());
							for(LogicSoWarefreezeItemDO item : cwfItems){
								// 匹配的产品
								if(item.getProdNo().equals(curSwItem2.getProdNo())
										&& item.getStatus().equals(curSwItem2.getStatus())
										){
									//足够的可冻结出库数量
									if(curCkBQty > LogicSoBeanUtil.getInstance().calcFreezeItemCanUnfreezeBQty(item)){
										throw new SyBaseException(swfDo.getNo()+"冻结申请单据,"+item.getProdNo()+"产品编码,冻结数量不足出库");
									}
									
									item.setSjdjCkBQty(item.getSjdjCkBQty()+curCkBQty);
									item.setSjdjCkQty(item.getSjdjCkQty()+curCkQty);
									//持久化
									logicSoWarefreezeItemDAO.updateLogicSoWarefreezeItemDO(item);
								}
							}
							//缓存，以便计算冻结标记
							soWarefreezeMap.put(swfDo.getNo(), swfDo);
							soWarefreezeItemMap.put(swfDo.getNo(), cwfItems);
						}
					}
					
					
					LogicSoDO soToDb = new LogicSoDO();
					//是否完全出库
					boolean isSoAllOutbound = true;
					for(LogicSoItemDO curSoItem :soItems){
						//检查出库状态
						if(curSoItem.getProdBQuantity() > curSoItem.getCkBQuantity()){
							isSoAllOutbound = false;
						}
						
					}
					int wareStatus = true==isSoAllOutbound?2:1;
					
					//有冻结时，冻结标记处理 
					if(1== logicSoDO.getFrozenStatus() || 2== logicSoDO.getFrozenStatus()){
						//是否完全冻结出库 1.无效，4生效并完全解冻出库，2生效并部分解冻出库
						boolean isSoFrozenAllOut = true;//
						for(LogicSoItemDO curSoItem :soItems){
							//有冻结标记时，检查是否完全冻结出库情况
							if(0 < curSoItem.getFrozenBQuantity()){
								isSoFrozenAllOut = false;
							}
						}
						
						if(true==isSoAllOutbound && false == isSoFrozenAllOut){
							throw new SyBaseException(logicSoDO.getNo()+"销售订单单据,订单完全出库，但冻结产品未完全解冻出库");
						}
						
						if(true == isSoFrozenAllOut){
							//销售订单完全解冻出库
							soToDb.setFrozenStatus(4);
						}else if(null != swItemList2 && swItemList2.size() > 0){
							//部分冻结出库
							soToDb.setFrozenStatus(2);
						}
					}
					
					//持久化销售订单
					soToDb.setId(logicSoDO.getId());
					soToDb.setWareStatus(wareStatus);
					logicSoDAO.updateLogicSoDO(soToDb);
					
					//冻结申请、冻结处理的全部解冻标记
					if(null != swItemList2){
						boolean isSowareFreezeAllOutbound = true;
						boolean isSowareFreezeDealAllOutbound = true;
						
						//查询全部冻结申请单并处理
						Set<String> sowareFreezeKey = soWarefreezeMap.keySet();
						if(null != sowareFreezeKey){
							for(String tmpNo : sowareFreezeKey){
								List<LogicSoWarefreezeItemDO> swfItemList = soWarefreezeItemMap.get(tmpNo);
								for(LogicSoWarefreezeItemDO item : swfItemList){
									if(0!=LogicSoBeanUtil.getInstance().calcFreezeItemCanUnfreezeBQty(item)){
										isSowareFreezeAllOutbound = false;
									}
								}
								
								if(true == isSowareFreezeAllOutbound){
									LogicSoWarefreezeDO soWarefreezeDO = soWarefreezeMap.get(tmpNo);
									soWarefreezeDO.setFrozenStatus(4);//?
									logicSoWarefreezeDAO.updateLogicSoWarefreezeDO(soWarefreezeDO);
								}
							}
						}
						
						
						//查询全部冻结处理单并处理
						Set<String> sowareFreezedealKey = soWarefreezedealMap.keySet();
						if(null != sowareFreezedealKey){
							for(String tmpNo : sowareFreezedealKey){
								List<LogicSoWarefreezedealItemDO> swfdItemList = soWarefreezedealItemMap.get(tmpNo);
								for(LogicSoWarefreezedealItemDO item : swfdItemList){
									if(0!=LogicSoBeanUtil.getInstance().calcFreezeDealItemCanUnfreezeBQty(item)){
										isSowareFreezeDealAllOutbound = false;
									}
								}
								
								LogicSoWarefreezedealDO soWarefreezedealDO = soWarefreezedealMap.get(tmpNo);
								soWarefreezedealDO.setUnfrozenStatus((true == isSowareFreezeDealAllOutbound)?2:1);//全部解冻
								logicSoWarefreezedealDAO.updateLogicSoWarefreezedealDO(soWarefreezedealDO);
							}
							
							
						}
						
						if(true == isSoAllOutbound){
							if(true != isSowareFreezeAllOutbound){
								logger.error(logicSoDO.getNo()+"销售订单完全出库，但其下的冻结申请单未完全解冻");
							}
							if(true != isSowareFreezeDealAllOutbound){
								logger.error(logicSoDO.getNo()+"销售订单完全出库，但其下的冻结处理单未完全解冻");
							}
						}
					}
					
					// 持久化出库单
					bean.setApprover(user.getName());// 二级
					bean.setApproverName(user.getRealName());
					bean.setWareStatus(wareStatus);
					result = logicSoWareDAO.updateLogicSoWareDO(bean);
					// 持久化出库单item
					saveOrUpdateItems(swItemList,swItemList2, bean);
					
				} else if (3 == iToFlag) {// 二级驳回到草稿
					// 持久化出库单
					bean.setApprover(user.getName());// 二级
					bean.setApproverName(user.getRealName());
					result = logicSoWareDAO.updateLogicSoWareDO(bean);
				} else {
					throw new SyBaseException("ParamFlag不合法：" + iToFlag);
				}
			}
		} catch (Exception e) {
			// e.printStackTrace();
			logger.error(e.getMessage(), e);
			throw new SyBaseException(GlobalResLoader.getOpfailed()
					+ e.getMessage());
		}
	}


	@Override
	public List<LogicSoWareItemDO> findItemListBypoId(String id)
			throws SyBaseException {
		return logicSoWareDAO.finditembypoid(id);
	}

	/**
	 * 单据的子项持久化
	 * 
	 * @param soItemlist
	 * @param soItemlist2
	 * @param curAP
	 */
	private void saveOrUpdateItems(List<LogicSoWareItemDO> soItemlist,List<LogicSoWareItemDO> soItemlist2,
			LogicSoWareDO curAP) {
		// 删除本订单下的item
		if (null != curAP.getId()) {
			List<LogicSoWareItemDO> logicSoWareItemDO = logicSoWareItemDAO.findItemListBysowareId(curAP.getId());
			if(logicSoWareItemDO != null){
				for (int i = 0; i < logicSoWareItemDO.size(); i++) {
						logicSoWareItemBatchDAO.deleteByItemBatchId(logicSoWareItemDO.get(i).getId());
						logicSoWareItemFreezedealbatchDAO.deleteByfreezedealItemid(logicSoWareItemDO.get(i).getId());
					
				}
			}
			logicSoWareItemDAO.deleteLogicSoWareItemDOBySoWareId(curAP.getId());
		}
		
		// 插入单据的item
		if (null != soItemlist) {
			for (LogicSoWareItemDO soItemDO : soItemlist) {
				// 对需要处理的item进行赋值
				String wareid =IDCodeTypeUtil.getId();
				soItemDO.setId(wareid);
				soItemDO.setSowareId(curAP.getId());
				soItemDO.setSowareNo(curAP.getNo());
				soItemDO.setSoNo(curAP.getSoNo());
				soItemDO.setCliNo(curAP.getCliNo());
				soItemDO.setCliName(curAP.getCliName());

				logicSoWareItemDAO.insertLogicSoWareItemDO(soItemDO);
				if(soItemDO.getItemBatch() != null && !"".equals(soItemDO.getItemBatch().trim())){
						List<LogicSoWareItemBatchDO> itemBatchDOs = JSONArray.parseArray(soItemDO.getItemBatch(),LogicSoWareItemBatchDO.class);
						for (int i = 0; i < itemBatchDOs.size(); i++) {
							itemBatchDOs.get(i).setId(IDCodeTypeUtil.getId());
							itemBatchDOs.get(i).setWareitemid(wareid);
							logicSoWareItemBatchDAO.insertLogicSoWareItemBatchDO(itemBatchDOs.get(i));
						}
				}
			}
		}
		
		// 插入单据的item
		if (null != soItemlist2) {
			for (LogicSoWareItemDO soItemDO : soItemlist2) {
				// 对需要处理的item进行赋值
				String wareid = IDCodeTypeUtil.getId();
				soItemDO.setId(wareid);
				soItemDO.setSowareId(curAP.getId());
				soItemDO.setSowareNo(curAP.getNo());
				soItemDO.setSoNo(curAP.getSoNo());
				soItemDO.setCliNo(curAP.getCliNo());
				soItemDO.setCliName(curAP.getCliName());

				logicSoWareItemDAO.insertLogicSoWareItemDO(soItemDO);
				if(soItemDO.getItemBatch() != null && !"".equals(soItemDO.getItemBatch().trim())){
					List<LogicSoWareItemFreezedealbatchDO> itemBatchDOs = JSONArray.parseArray(soItemDO.getItemBatch(),LogicSoWareItemFreezedealbatchDO.class);
					for (int i = 0; i < itemBatchDOs.size(); i++) {
						itemBatchDOs.get(i).setId(IDCodeTypeUtil.getId());
						itemBatchDOs.get(i).setFreezedealitemid(wareid);
						logicSoWareItemFreezedealbatchDAO.insertLogicSoWareItemFreezedealbatchDO(itemBatchDOs.get(i));
					}
				}
			}
		}
	}
	
	/**
	 * 根据销售订单编号获取销售订单实体
	 * @param no
	 * @return
	 */
	private LogicSoDO findLogicSoDOByNo(String no) {
		LogicSoDO logicSoDO = null;
		if(null != no && !"".equals(no.trim())){
			
			SearchConditions scs = new SearchConditions();
			scs.addCondition("no", no, SearchCondition.OP_EQUAL);
			List<LogicSoDO> list = logicSoDAO.find(scs);
	        if(null != list && list.size() > 0){
	        	logicSoDO = list.get(0);
	        }
		}
		
		return logicSoDO;
	}
	
//	/**
//	 * 订单编号对应的全部冻结产品
//	 * @param soNo
//	 * @return
//	 */
//	private List<LogicSoWarefreezedealItemDO> findSoWarefreezedealItemsBySoNo(String soNo){
//		
//		List<LogicSoWarefreezedealItemDO> list = new ArrayList<LogicSoWarefreezedealItemDO>();
//		SearchConditions scs = new SearchConditions();
//		scs.addCondition("so_no", soNo, SearchCondition.OP_EQUAL);
//		scs.addCondition("billstatus", "2", SearchCondition.OP_EQUAL);//完结的冻结处理单据
//		List<LogicSoWarefreezedealDO> ls = logicSoWarefreezedealDAO.find(scs);
//		if(null != ls && ls.size() > 0){
//			for(LogicSoWarefreezedealDO logicSoWarefreezedealDO :ls){
//				list = logicSoWarefreezedealItemDAO.findItemListByswfdId(logicSoWarefreezedealDO.getId());
//			}
//			
//        }
//		
//		return list;
//	}
	
//	/**
//	 * 根据key分组产品冻结列表
//	 * @param swfdMap
//	 * @param swfdDo
//	 * @param list
//	 * @return key:仓库编码+物料编码+批次
//	 * 
//	 */
//	private Map<String,List<LogicSoWarefreezedealItemDO>> groupSoWarefreezedealItemsMap(Map<String,List<LogicSoWarefreezedealItemDO>> swfdMap, LogicSoWarefreezedealDO swfdDo,List<LogicSoWarefreezedealItemDO> list){
////		Map<String,List<LogicSoWarefreezedealItemDO>> map = new HashMap<String,List<LogicSoWarefreezedealItemDO>>();
//		for(LogicSoWarefreezedealItemDO item : list){
//			String mapKey = swfdDo.getWhcode()+item.getProdNo()+item.getProdBatch();
//			List<LogicSoWarefreezedealItemDO> list2 = swfdMap.get(mapKey);
//			if(null==list2){
//				list2 = new ArrayList<LogicSoWarefreezedealItemDO>();
//			}
//			list2.add(item);
//			swfdMap.put(mapKey, list2);
//		}
//		return swfdMap;
//	}
	
	/**
	 * 普通出库
	 * @param curAP
	 * @param curSwItem2
	 * @param qty
	 * @param jqty
	 * @param user
	 */
	private void ptckWhAff(LogicSoWareDO curAP,LogicSoWareItemDO curSwItem2,double qty,double jqty,User user){
		LogicWhAffDO lwhaff = new LogicWhAffDO();
		if("Y".equals(curSwItem2.getOpenBatch())){
			if(curSwItem2.getItemBatch() != null && !"".equals(curSwItem2.getItemBatch().trim())){
				List<LogicSoWareItemBatchDO> itemBatchDOs = JSONArray.parseArray(curSwItem2.getItemBatch(),LogicSoWareItemBatchDO.class);
				for (int i = 0; i < itemBatchDOs.size(); i++) {
				lwhaff.setBillCode(curAP.getNo());
				lwhaff.setBillType("SP");// 设置为销售编码的头字符
				lwhaff.setWhCode(curAP.getWhcode());
				lwhaff.setWhname(curAP.getWhname());
				lwhaff.setBatch(itemBatchDOs.get(i).getProdBatch());
				lwhaff.setUnit(curSwItem2.getProdUnit());
				lwhaff.setJunit(curSwItem2.getProdBUnit());
				if(null !=curSwItem2.getProdPrice()){
					lwhaff.setPrice(Double.valueOf(curSwItem2.getProdPrice().toString()));// ?
				}
				lwhaff.setCode(curSwItem2.getProdNo());
				lwhaff.setName(curSwItem2.getProdName());
				lwhaff.setSpec(curSwItem2.getProdSpecDesc());
				lwhaff.setBrand(curSwItem2.getProdModel());// ?
				lwhaff.setHubCode(curSwItem2.getHubcode());
				lwhaff.setHubName(curSwItem2.getHubname());
				lwhaff.setStatus(itemBatchDOs.get(i).getStatus());// 库存等级
				lwhaff.setQuantity(-itemBatchDOs.get(i).getProdSfquantity());
				lwhaff.setJquantity(-itemBatchDOs.get(i).getProdBSfquantity());// 出库，负数
				logicWhAffStockService
					.updateWhAffstockQuantity(lwhaff,user,false);
				}
			}
		}else{
			lwhaff.setBillCode(curAP.getNo());
			lwhaff.setBillType("SP");// 设置为销售编码的头字符
			lwhaff.setWhCode(curAP.getWhcode());
			lwhaff.setWhname(curAP.getWhname());
			lwhaff.setBatch("NoBatch");
			lwhaff.setUnit(curSwItem2.getProdUnit());
			lwhaff.setJunit(curSwItem2.getProdBUnit());
			if(null !=curSwItem2.getProdPrice()){
				lwhaff.setPrice(Double.valueOf(curSwItem2.getProdPrice().toString()));// ?
			}
			lwhaff.setCode(curSwItem2.getProdNo());
			lwhaff.setName(curSwItem2.getProdName());
			lwhaff.setSpec(curSwItem2.getProdSpecDesc());
			lwhaff.setBrand(curSwItem2.getProdModel());// ?
			lwhaff.setHubCode(curSwItem2.getHubcode());
			lwhaff.setHubName(curSwItem2.getHubname());
			lwhaff.setStatus(curSwItem2.getStatus());// 库存等级
			lwhaff.setQuantity(-qty);
			lwhaff.setJquantity(-jqty);// 出库，负数
			logicWhAffStockService
				.updateWhAffstockQuantity(lwhaff,user,false);
		}
		
	}
	
	/**
	 * 冻结出库
	 * @param curAP
	 * @param curSwItem
	 * @param qty
	 * @param jqty
	 * @param user
	 */
	private void djckWhAff(LogicSoWareDO curAP,LogicSoWareItemDO curSwItem,double qty,double jqty,User user){
		//冻结库存出库----start
		if("Y".equals(curSwItem.getOpenBatch())){
			if(curSwItem.getItemBatch() != null && !"".equals(curSwItem.getItemBatch().trim())){
				List<LogicSoWareItemFreezedealbatchDO> itemBatchDOs = JSONArray.parseArray(curSwItem.getItemBatch(),LogicSoWareItemFreezedealbatchDO.class);
				for (int i = 0; i < itemBatchDOs.size(); i++) {
				LogicWhAffDO lwhaff = new LogicWhAffDO();
				lwhaff.setBillCode(curAP.getNo());
				lwhaff.setBillType("SP");//原XS 设置为销售出库编码的头字符，供报表使用
				lwhaff.setWhCode(curAP.getWhcode());
				lwhaff.setWhname(curAP.getWhname());
				lwhaff.setBatch(itemBatchDOs.get(i).getProdBatch());
				lwhaff.setUnit(curSwItem.getProdUnit());
				lwhaff.setJunit(curSwItem.getProdBUnit());
				if(null != curSwItem.getProdPrice()){
					lwhaff.setPrice(Double.valueOf(curSwItem.getProdPrice().toString()));
				}
				lwhaff.setCode(curSwItem.getProdNo());
				lwhaff.setName(curSwItem.getProdName());
				lwhaff.setSpec(curSwItem.getProdSpecDesc());
				lwhaff.setBrand(curSwItem.getProdModel());// ?
				// lwhaff.setCreategscode(lpwd.getCreategscode());
				// lwhaff.setCreategsname(lpwd.getCreategsname());
				lwhaff.setHubCode(curSwItem.getHubcode());
				lwhaff.setHubName(curSwItem.getHubname());
				// lwhaff.setStockPrice(Double.valueOf(swProduct.get));//?//TODO含税
				lwhaff.setStatus("4");// 冻结仓库 
				lwhaff.setQuantity(-itemBatchDOs.get(i).getProdSfquantity());// 减少库存
				lwhaff.setJquantity(-itemBatchDOs.get(i).getProdBSfquantity());
				logicWhAffStockService.updateWhAffstockQuantity(lwhaff,user,false);
				//冻结库存出库----end
				
				}
				}
		}else{
			LogicWhAffDO lwhaff = new LogicWhAffDO();
			lwhaff.setBillCode(curAP.getNo());
			lwhaff.setBillType("SP");//原XS 设置为销售出库编码的头字符，供报表使用
			lwhaff.setWhCode(curAP.getWhcode());
			lwhaff.setWhname(curAP.getWhname());
			lwhaff.setBatch("NoBatch");
			lwhaff.setUnit(curSwItem.getProdUnit());
			lwhaff.setJunit(curSwItem.getProdBUnit());
			if(null != curSwItem.getProdPrice()){
				lwhaff.setPrice(Double.valueOf(curSwItem.getProdPrice().toString()));
			}
			lwhaff.setCode(curSwItem.getProdNo());
			lwhaff.setName(curSwItem.getProdName());
			lwhaff.setSpec(curSwItem.getProdSpecDesc());
			lwhaff.setBrand(curSwItem.getProdModel());// ?
			// lwhaff.setCreategscode(lpwd.getCreategscode());
			// lwhaff.setCreategsname(lpwd.getCreategsname());
			lwhaff.setHubCode(curSwItem.getHubcode());
			lwhaff.setHubName(curSwItem.getHubname());
			// lwhaff.setStockPrice(Double.valueOf(swProduct.get));//?//TODO含税
			lwhaff.setStatus("4");// 冻结仓库 
			lwhaff.setQuantity(-qty);// 减少库存
			lwhaff.setJquantity(-jqty);
			logicWhAffStockService.updateWhAffstockQuantity(lwhaff,user,false);
		}
		
		}

	@Override
	public Integer deleteBizRemoved(String id) throws SyBaseException {
		// TODO Auto-generated method stub
		return null;
	}
}
